// fs.cpp: File System

#include "sfs/fs.h"
#include <cmath>
#include <cstring>
#include <iostream>

using namespace std;

#include <algorithm>

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

// Debug file system -----------------------------------------------------------

void FileSystem::debug(Disk *disk) {
    Block block;

    // Read Superblock
    disk->read(0, block.Data);

    printf("SuperBlock:\n");
    printf("    %s\n", block.Super.MagicNumber == MAGIC_NUMBER ? "magic number is valid" : "magic number is invalid");
    printf("    %u blocks\n"         , block.Super.Blocks);
    printf("    %u inode blocks\n"   , block.Super.InodeBlocks); // inode表占总块数的10%
    printf("    %u inodes\n"         , block.Super.Inodes);  // 总inode数量

    // 打印inode位图信息
    uint32_t enable;
    printf("Inode Bitmap:\n");
    enable = std::count(i_map.begin(), i_map.end(), false);
    printf("    总块数: %u, 可用: %u, 下一个可用inode号: %u\n", block.Super.Inodes, enable, block.Super.next_available_ino);
    printf("    已使用: \n");
    printf("    ");
    for (uint32_t i = 0; i < block.Super.Inodes; i++) {
        if(i_map.empty()) {
            printf("请先挂载文件系统\n");
            exit(0);
        }
        if (!i_map.empty() && i_map[i]) {  // 检查vector不为空且位为true
            printf("%u ", i);
        }
    }
    printf("\n");

    // 打印块位图信息
    printf("Block Bitmap:\n");
    enable = std::count(b_map.begin(), b_map.end(), false);
    printf("    总块数: %u, 可用: %u, 下一个可用块地址: %u\n", block.Super.Blocks, enable, block.Super.next_available_blk);
    printf("    已使用: \n");
    printf("    ");
    for (uint32_t i = 0; i < block.Super.Blocks; i++) {
        if(b_map.empty()) {
            printf("请先挂载文件系统\n");
            exit(0);
        }
        if (!b_map.empty() && b_map[i]) {  // 检查vector不为空且位为true
            printf("%u ", i);
        }
    }
    printf("\n");

    uint32_t num_inode_blocks = block.Super.InodeBlocks;
    // Read Inode blocks
    for (uint32_t i = INODE_START_ADDR; i <= num_inode_blocks; i++) { // 遍历inode块，inode表设置初始偏移为INODE_START_ADDR
        disk->read(i, block.Data);
        for (uint32_t j = 0; j < INODES_PER_BLOCK; j++) { // 遍历inode块中的inode
            if (block.Inodes[j].Valid != 0) {  // 修改Valid的判断方式
                printf("Inode %u:\n", j + ((i-1) * INODES_PER_BLOCK)); // 计算这是第几个inode
                printf("    type: %s    name: %s\n", block.Inodes[j].type == 1 ? "directory" : "file", block.Inodes[j].dentry.name.c_str());
                printf("    size: %u bytes\n", block.Inodes[j].Size); // 输出该inode对应的文件大小
                printf("    direct blocks:");
                for (uint32_t k = 0; k < POINTERS_PER_INODE && block.Inodes[j].Direct[k]; k++) { // 打印直接指针指向的数据块地址
                    printf(" %u", block.Inodes[j].Direct[k]);
                }
                printf("\n");
                if (block.Inodes[j].Indirect != 0) { // 如果该inode有间接指针
                    printf("    indirect block: %u\n", block.Inodes[j].Indirect);
                    Block indirect;
                    disk->read(block.Inodes[j].Indirect, indirect.Data); // 读取间接指针指向的数据块地址，文件的直接指针和间接指针指向的是实际存放数据的数据块地址，目录的直接指针和间接指针指向的是存放子文件和子目录inode数据块的地址，注意一个数据块中肯定不止一个inode。
                    printf("    indirect data blocks:");
                    for (uint32_t k = 0; k < POINTERS_PER_BLOCK && indirect.Pointers[k]; k++) { 
                        printf(" %u", indirect.Pointers[k]); 
                    }
                    printf("\n");
                }
            }
        }
    }

    printf("%lu disk block reads\n", disk->getReads());
    printf("%lu disk block writes\n", disk->getWrites());
}

bool FileSystem::Init_Map(Disk *disk, Block &block) {
    /*********初始化位图*********/
    i_map.resize(block.Super.Inodes, false);  // 调整inode位图大小并初始化为false
    b_map.resize(block.Super.Blocks, false);  // 调整块位图大小并初始化为false

    // 标记已使用的系统块（超级块和inode块）
    b_map[0] = true;                            // 超级块已使用
    for (uint32_t i = INODE_START_ADDR; i <= block.Super.InodeBlocks; i++) {
        b_map[i] = true;                        // 标记inode块已使用
    }

    // 根据Valid和Indirect判断是否有文件存在，初始化i_map
    Block inode_block;
    for (uint32_t i = INODE_START_ADDR; i <= block.Super.InodeBlocks; i++) {
        disk->read(i, inode_block.Data);
        for (uint32_t j = 0; j < INODES_PER_BLOCK; j++) {
            uint32_t inode_number = ((i-1) * INODES_PER_BLOCK) + j;
            i_map[inode_number] = (inode_block.Inodes[j].Valid != 0);  // 修改Valid的判断方式
            
            if (inode_block.Inodes[j].Valid != 0) {  // 修改Valid的判断方式
                // 标记直接块
                for (uint32_t k = 0; k < POINTERS_PER_INODE && inode_block.Inodes[j].Direct[k]; k++) {
                    b_map[inode_block.Inodes[j].Direct[k]] = true;
                }
                
                // 标记间接块
                if (inode_block.Inodes[j].Indirect != 0) {
                    b_map[inode_block.Inodes[j].Indirect] = true;  // 标记间接块本身
                    Block indirect_block;
                    disk->read(inode_block.Inodes[j].Indirect, indirect_block.Data);
                    for (uint32_t k = 0; k < POINTERS_PER_BLOCK && indirect_block.Pointers[k]; k++) {
                        b_map[indirect_block.Pointers[k]] = true;  // 标记间接块指向的数据块
                    }
                }
            }
        }
    }
    return true;
}

// Format file system ----------------------------------------------------------
/*格式化，写入磁盘*/
bool FileSystem::format(Disk *disk) {
    // Write superblock
    Block block; // 定义一个块，作为临时数据缓冲
    memset(&block, 0, sizeof(Block)); // 将块初始化为0
    block.Super.MagicNumber = MAGIC_NUMBER; // 初始化块标识符
    block.Super.Blocks = disk->size(); // 初始化块组中块数量
    int InodeBlocks_Reversed = ceil(block.Super.Blocks * 0.1);
    block.Super.InodeBlocks = InodeBlocks_Reversed;  // 初始化inode table块大小，为总块数的10%
    block.Super.Inodes = InodeBlocks_Reversed * INODES_PER_BLOCK; // 初始化inode数量，因为一个块为4KB，一个inode为32B，所以INODES_PER_BLOCK为4KB/32B=128.
    
    block.Super.free_inode_count = block.Super.Inodes;  // 初始时所有inode都是空闲的
    block.Super.s_free_block_count = block.Super.Blocks - block.Super.InodeBlocks - 1;  // 减去inode块和超级块
    block.Super.next_available_ino = 0;  // 下一个可用的inode号从0开始
    block.Super.next_available_blk = block.Super.InodeBlocks + 1;  // 超级块1+inode块数
    block.Super.DATA_START_ADDR = block.Super.InodeBlocks + INODE_START_ADDR;  // 数据块开始地址
    // 初始化所有inode块和数据块
    Block inode_block;  // 使用新的变量名
    memset(&inode_block, 0, sizeof(Block));  // 将块初始化为0
    for (uint32_t i = INODE_START_ADDR; i <= block.Super.InodeBlocks; i++) {
        disk->write(i, (char*)&inode_block);  // 写入空的inode块
    }

    // 初始化所有数据块
    Block data_block;
    memset(&data_block, 0, sizeof(Block));  // 将数据块初始化为0
    for (uint32_t i = block.Super.InodeBlocks + 1; i < block.Super.Blocks; i++) {
        disk->write(i, (char*)&data_block);  // 写入空的数据块
    }

    // Write superblock
    disk->write(0, (char*)&block);

    // 初始化位图
    if (!Init_Map(disk, block)) {
        printf("初始化位图失败");
        return false;
    }
    printf("初始化位图成功\n");
    printf("开始mount自检....\n");
    if (!this->mount(disk)) {
        printf("mount自检失败\n");
        return false;
    }
    printf("mount自检成功\n");
    this->debug(disk);
    return true;
}

// Mount file system -----------------------------------------------------------

bool FileSystem::mount(Disk *disk) {
    if (disk == nullptr) return false;  // 检查磁盘是否存在

    // 读取超级块
    Block block;
    disk->read(0, block.Data);

    // 验证超级块
    if (block.Super.MagicNumber != MAGIC_NUMBER) {
        return false;  // 魔数不匹配
    }
    printf("超级块合法\n");

    // 验证块数
    if (block.Super.Blocks != disk->size()) {
        return false;  // 块数不匹配
    }
    printf("块数合法 \n");

    // 验证inode块数和inode数量
    if (block.Super.InodeBlocks <= 0 || 
        block.Super.Inodes <= 0 || 
        block.Super.InodeBlocks > block.Super.Blocks ||
        block.Super.Inodes != block.Super.InodeBlocks * INODES_PER_BLOCK) {
        return false;  // inode相关参数不合法
    }
    printf("inode相关参数合法\n");
    // 初始化用户
    printf("开始初始化用户....\n");
    if (!Init_user()) {
        printf("初始化用户失败\n");
        return false;
    }
    printf("初始化用户成功\n");

    // 初始化目录结构
    printf("开始挂载目录....\n");
    if (!Init_dir(disk)) {
        printf("初始化目录结构失败\n");
        return false;
    }
    printf("目录挂载成功\n");


    return true;
}



// Inode stat ------------------------------------------------------------------

ssize_t FileSystem::stat(size_t inumber) {
    // Load inode information
    return 0;
}

// Read from inode -------------------------------------------------------------

ssize_t FileSystem::read(Disk *disk, size_t inumber, char *data, size_t length) {
    Block block;
    
    // 1. 计算文件inode的物理地址和inode块内偏移
    uint32_t inode_block = INODE_START_ADDR + (inumber / INODES_PER_BLOCK);
    uint32_t inode_offset = inumber % INODES_PER_BLOCK;
    
    // 2. 读取inode
    disk->read(inode_block, block.Data);
    Inode &inode = block.Inodes[inode_offset];
    
    // 3. 检查inode是否有效
    if (!inode.Valid) {
        printf("无效的inode\n");
        return -1;
    }
    
    // 4. 调整读取长度，确保不会超出文件末尾
    if (length > inode.Size) {
        length = inode.Size;
    }
    
    // 5. 计算需要读取的块
    size_t start_block = 0;  // 从第一个块开始
    size_t end_block = (length - 1) / Disk::BLOCK_SIZE;  // 结束块号
    size_t read_bytes = 0;  // 已读取的字节数
    
    // 6. 读取数据
    for (size_t i = start_block; i <= end_block; i++) {
        // 获取数据块号
        uint32_t block_number;
        if (i < POINTERS_PER_INODE) {
            // 读取直接块
            block_number = inode.Direct[i];
        } else {
            // 间接块
            if (inode.Indirect == 0) {
                break;  // 没有间接块
            }
            Block indirect_block;
            disk->read(inode.Indirect, indirect_block.Data);
            block_number = indirect_block.Pointers[i - POINTERS_PER_INODE];
        }
        
        if (block_number == 0) {  // 块地址为0表示没有分配块
            continue;  // 继续检查下一个块
        }
        
        // 读取数据块
        Block data_block;
        disk->read(block_number, data_block.Data);
        
        // 计算这个块中要读取的字节数, 如果读到最后一块，最后一块没有写满数据，就只读取剩余的数据
        size_t block_length = Disk::BLOCK_SIZE;
        if (read_bytes + block_length > length) {
            block_length = length - read_bytes;
        }
        
        // 复制数据
        memcpy(data + read_bytes, data_block.Data, block_length);//memcpy(目标地址，源地址，复制字节数)
        read_bytes += block_length;
    }
    
    return read_bytes;
}

// Write to inode --------------------------------------------------------------

ssize_t FileSystem::write(Disk *disk, size_t inumber, char *data, size_t length) {
    Block block;
    Block super_block;
    
    // 1. 读取超级块
    disk->read(0, super_block.Data);
    SuperBlock &sb = super_block.Super;
    
    // 2. 计算inode块的物理地址和块内偏移
    uint32_t inode_block = INODE_START_ADDR + (inumber / INODES_PER_BLOCK);
    uint32_t inode_offset = inumber % INODES_PER_BLOCK;
    
    // 3. 读取inode
    disk->read(inode_block, block.Data);
    Inode &inode = block.Inodes[inode_offset];
    
    // 4. 检查inode是否有效
    if (!inode.Valid) {
        printf("无效的inode\n");
        return -1;
    }
    
    // 5. 计算需要的块数
    size_t start_block = 0;  // 一个计数器而已，可以换为i
    size_t end_block = (length - 1) / Disk::BLOCK_SIZE; // 计算循环写入次数
    size_t write_bytes = 0;
    
    // 6. 检查是否需要间接块
    if (end_block >= POINTERS_PER_INODE && !inode.Indirect) {
        // 分配间接块
        int indirect_block_num = allocate_block(disk);
        if (indirect_block_num == -1) {
            printf("没有空闲块用于间接块\n");
            return -1;
        }
        
        inode.Indirect = indirect_block_num;
        
        // 初始化间接块
        Block indirect_block;
        memset(indirect_block.Data, 0, sizeof(indirect_block.Data));
        disk->write(indirect_block_num, indirect_block.Data);
    }
    
    // 7. 写入数据
    for (size_t i = start_block; i <= end_block; i++) {
        // 获取或分配数据块
        uint32_t block_number;
        if (i < POINTERS_PER_INODE) {
            // 直接块
            if (!inode.Direct[i]) {
                // 分配新块
                int new_block = allocate_block(disk);
                if (new_block == -1) {
                    printf("没有空闲块\n");
                    break;
                }
                inode.Direct[i] = new_block;
            }
            block_number = inode.Direct[i];
        } else {
            // 间接块
            Block indirect_block;
            disk->read(inode.Indirect, indirect_block.Data);
            size_t indirect_index = i - POINTERS_PER_INODE; // 计算间接块指针数组的下标
            
            if (!indirect_block.Pointers[indirect_index]) {
                // 分配新块
                int new_block = allocate_block(disk);
                if (new_block == -1) {
                    printf("没有空闲块\n");
                    break;
                }
                indirect_block.Pointers[indirect_index] = new_block;
                disk->write(inode.Indirect, indirect_block.Data); // 写回间接指针指向的间接块
            }
            block_number = indirect_block.Pointers[indirect_index];  // 获取间接块指针数组中指向的的数据块号
        }
        
        // 写入数据块临时变量
        Block data_block;
        
        // 计算写入长度，大于说明已经写到最后一个块了，最后一个块写不满
        size_t block_length = Disk::BLOCK_SIZE; 
        if (write_bytes + block_length > length) {
            block_length = length - write_bytes;
        }
        
        // 复制数据
        memcpy(data_block.Data, data + write_bytes, block_length); // memcpy(目标地址，源地址，复制字节数)
        disk->write(block_number, data_block.Data); // 将数据写入间接数据块
        write_bytes += block_length;
    }
    
    // 8. 更新文件大小
    inode.Size = length;
    
    // 9. 写回inode和超级块
    disk->write(inode_block, block.Data);
    disk->write(0, super_block.Data);
    
    return write_bytes;
}

// 实现inode分配函数，使用首次适应算法
int FileSystem::allocate_inode(Disk *disk) {
    Block super_block;  // Block的构造函数会自动初始化
    disk->read(0, super_block.Data);
    SuperBlock &sb = super_block.Super;

    // 从next_available_ino开始查找
    for(uint32_t i = sb.next_available_ino; i < sb.Inodes; i++) {
        if(!i_map[i]) {
            i_map[i] = true;
            sb.free_inode_count--;
            sb.next_available_ino = i + 1;
            disk->write(0, super_block.Data);  // 写回超级块
            return i;
        }
    }
    
    // 如果上面没找到，从头开始再找一遍
    for(uint32_t i = 0; i < sb.next_available_ino; i++) {
        if(!i_map[i]) {
            i_map[i] = true;
            sb.free_inode_count--;
            sb.next_available_ino = i + 1;
            disk->write(0, super_block.Data);  // 写回超级块
            return i;
        }
    }
    
    return -1; // 没有可用的inode
}

// 实现block分配函数，使用首次适应算法
int FileSystem::allocate_block(Disk *disk) {
    Block super_block;  // Block的构造函数会自动初始化
    disk->read(0, super_block.Data);
    SuperBlock &sb = super_block.Super;

    // 检查是否还有空闲块
    if (sb.s_free_block_count == 0) {
        printf("没有空闲的数据块\n");
        return -1;
    }

    // 从next_available_blk开始查找
    for(uint32_t i = sb.next_available_blk; i < sb.Blocks; i++) {
        if(!b_map[i]) {
            b_map[i] = true;
            sb.s_free_block_count--;
            sb.next_available_blk = i + 1;
            disk->write(0, super_block.Data);  // 写回超级块
            return i;
        }
    }
    
    // 如果上面没找到，从头开始再找一遍
    // 注意：从数据块起始地址开始查找
    for(uint32_t i = sb.DATA_START_ADDR; i < sb.next_available_blk; i++) {
        if(!b_map[i]) {
            b_map[i] = true;
            sb.s_free_block_count--;
            sb.next_available_blk = i + 1;
            disk->write(0, super_block.Data);  // 写回超级块
            return i;
        }
    }
    
    return -1; // 没有可用的数据块
}

bool FileSystem::mkdir(Disk *disk, string dir_path) {
    Block block;
    
    // 1. 检查路径名是否合法
    if (dir_path.empty() || dir_path.length() > 255) {
        printf("路径名不合法\n");
        return false;
    }

    // 2. 解析路径
    string parent_path = "/";  // 父目录的路径
    string dir_name;          // 要创建的目录名
    uint32_t parent_ino;      // 父目录的inode号

    // 处理不同的路径格式
    if (dir_path[0] == '/') {
        // 绝对路径，从根目录开始
        parent_ino = 0;  // 根目录的inode号
        if (dir_path == "/") {
            printf("无法创建根目录\n");
            return false;
        }
        // 移除开头的'/'
        dir_path = dir_path.substr(1);
        parent_path = "/";
    } else if (dir_path.substr(0, 2) == "./") {
        // 当前目录路径
        parent_ino = current_dir_ino;
        parent_path = current_dir;
        // 移除"./"
        dir_path = dir_path.substr(2);
    } else {
        // 相对路径，从当前目录开始
        parent_ino = current_dir_ino;
        parent_path = current_dir;
    }

    // 3. 如果路径中包含多级目录，需要逐级查找
    size_t pos = dir_path.find('/');
    while (pos != string::npos) {
        string segment = dir_path.substr(0, pos);
        dir_path = dir_path.substr(pos + 1);

        // 处理 ".." 目录
        if (segment == "..") {
            // 获取当前目录的inode
            uint32_t current_block = INODE_START_ADDR + (parent_ino / INODES_PER_BLOCK);
            uint32_t current_offset = parent_ino % INODES_PER_BLOCK;
            disk->read(current_block, block.Data);
            Inode &current_inode = block.Inodes[current_offset];
            
            // 获取父目录的物理地址
            auto it = current_inode.dentry.children.find("..");
            if (it == current_inode.dentry.children.end()) {
                printf("无法访问父目录\n");
                return false;
            }
            
            uint32_t parent_phys_addr = it->second;
            parent_ino = ((parent_phys_addr >> 16) - INODE_START_ADDR) * INODES_PER_BLOCK + (parent_phys_addr & 0xFFFF);
            
            // 更新父目录路径
            size_t last_slash = parent_path.find_last_of('/');
            if (last_slash == 0) {
                parent_path = "/";
            } else {
                parent_path = parent_path.substr(0, last_slash);
            }
        } else {
            // 读取当前目录的inode
            uint32_t current_block = INODE_START_ADDR + (parent_ino / INODES_PER_BLOCK);
            uint32_t current_offset = parent_ino % INODES_PER_BLOCK;
            disk->read(current_block, block.Data);
            Inode &current_inode = block.Inodes[current_offset];

            // 查找子目录
            auto it = current_inode.dentry.children.find(segment);
            if (it == current_inode.dentry.children.end()) {
                printf("路径不存在: %s\n", segment.c_str());
                return false;
            }

            // 更新父目录信息
            uint32_t child_phys_addr = it->second;
            parent_ino = ((child_phys_addr >> 16) - INODE_START_ADDR) * INODES_PER_BLOCK + (child_phys_addr & 0xFFFF);
            parent_path = parent_path == "/" ? "/" + segment : parent_path + "/" + segment;
        }
        
        pos = dir_path.find('/');
    }

    // 4. 最后一段是要创建的目录名
    dir_name = dir_path;
    if (dir_name == "." || dir_name == "..") {
        printf("无法创建名为 . 或 .. 的目录\n");
        return false;
    }

    // 5. 读取父目录的inode
    uint32_t parent_block = INODE_START_ADDR + (parent_ino / INODES_PER_BLOCK);
    uint32_t parent_offset = parent_ino % INODES_PER_BLOCK;
    uint32_t parent_phys_addr = (parent_block << 16) | parent_offset;  // 高16位是块号，低16位是块内偏移
    
    disk->read(parent_block, block.Data); // 读出当前块的数据(即当前目录的inode块地址)
    Inode &parent_inode = block.Inodes[parent_offset]; // 获取当前目录的inode

    // 6. 检查目录是否已存在
    if (parent_inode.dentry.children.find(dir_name) != parent_inode.dentry.children.end()) {
        printf("目录已存在: %s\n", dir_name.c_str());
        return false;
    }
    /***********再次简化，查找目录时只在内存中的dentry进行查找，如果没有则不会进一步对磁盘进行查找操作***********/

    // 4. 使用首次适应算法分配新的inode
    int new_ino = allocate_inode(disk);
    if (new_ino == -1) {
        printf("没有空闲inode\n");
        return false;
    }

    // 8. 初始化新目录的inode
    uint32_t new_inode_block = INODE_START_ADDR + (new_ino / INODES_PER_BLOCK);
    uint32_t new_inode_offset = new_ino % INODES_PER_BLOCK;
    uint32_t new_phys_addr = (new_inode_block << 16) | new_inode_offset;  // 高16位是块号，低16位是块内偏移
    
    disk->read(new_inode_block, block.Data);
    Inode &new_inode = block.Inodes[new_inode_offset];
    
    new_inode.Valid = 1;
    new_inode.Size = 64;  // . 和 .. 两个目录项，每个32字节
    new_inode.type = 1;  // 1表示目录
    new_inode.mode = DEFAULT_MODE;  // 默认权限 0x66 (rw-rw-)
    new_inode.uname = current_user;  // 设置目录所有者为当前用户
    new_inode.dentry.name = dir_name;
    memset(new_inode.Direct, 0, sizeof(new_inode.Direct));
    new_inode.Indirect = 0;

    // 9. 设置新目录的特殊目录项
    new_inode.dentry.children.clear();
    new_inode.dentry.children["."] = new_phys_addr;      // 当前目录
    new_inode.dentry.children[".."] = parent_phys_addr;  // 父目录

    // 10. 更新父目录
        // 打印调试信息
    printf("新目录名: %s 新目录子项数: %zu\n", dir_name.c_str(), new_inode.dentry.children.size
    ());
    parent_inode.dentry.children[dir_name] = new_phys_addr;  // 存储物理地址
    parent_inode.Size += 32;  // 增加一个目录项的大小
    /*******再次简化，目录下新增的目录直接不写入磁盘，直接放到内存的dentry，没有数据持久化******/
    
    // 11. 写回磁盘
    disk->write(parent_block, block.Data);
    disk->write(new_inode_block, block.Data);
    
    printf("目录创建成功: %s%s%s\n", 
           parent_path.c_str(),
           (parent_path == "/" ? "" : "/"),
           dir_name.c_str());
    return true;
}

// 初始化root用户
bool FileSystem::Init_user() {
    current_user = "root";  // 设置当前用户为root
    return true;
}

// 初始化目录结构
bool FileSystem::Init_dir(Disk *disk) {
    Block super_block;  // 单独的Block用于保存超级块
    Block inode_block;  // 用于操作inode的Block，临时变量
    
    // 1. 读取超级块
    disk->read(0, super_block.Data);
    
    // 2. 分配根目录的inode (inode 0)
    if (super_block.Super.free_inode_count == 0) {
        printf("没有空闲inode用于创建根目录\n");
        return false;
    }
    
    uint32_t root_ino = 0;  // 根目录用第一个inode
    uint32_t root_block = INODE_START_ADDR + (root_ino / INODES_PER_BLOCK);  // inode物理块号
    uint32_t root_offset = root_ino % INODES_PER_BLOCK;  // 块内偏移
    uint32_t root_phys_addr = (root_block << 16) | root_offset;  // 高16位是块号，低16位是块内偏移
    
    i_map[root_ino] = true;  // 标记为已使用
    super_block.Super.free_inode_count--;
    super_block.Super.next_available_ino = 1;  // 下一个可用inode从1开始
    
    // 3. 初始化根目录的inode
    disk->read(root_block, inode_block.Data); // 读取根目录所在inode数据块
    Inode &root_inode = inode_block.Inodes[root_offset]; // 读取inode的值
    
    root_inode.Valid = 1;
    root_inode.Size = 64;  // . 和 .. 两个目录项，每个32字节
    root_inode.type = 1;  // 1表示目录
    root_inode.mode = DEFAULT_MODE;
    root_inode.uname = current_user;  // root用户
    root_inode.dentry.name = "/";  // 根目录名为"/"
    memset(root_inode.Direct, 0, sizeof(root_inode.Direct));
    root_inode.Indirect = 0;

    // 设置根目录的特殊目录项
    root_inode.dentry.children.clear();  // 先清空children map
    root_inode.dentry.children["."] = root_phys_addr;   // 当前目录
    root_inode.dentry.children[".."] = root_phys_addr;  // 父目录，根目录的父目录指向自己

    // 打印调试信息
    printf("根目录children项数: %zu\n", root_inode.dentry.children.size());
    for (const auto &entry : root_inode.dentry.children) {
        printf("  键: '%s', 值: 0x%08X\n", entry.first.c_str(), entry.second);
    }

    // 4. 设置当前目录为根目录
    current_dir_ino = root_ino;
    current_dir = "/";
    
    // 5. 写回磁盘
    disk->write(0, super_block.Data);  // 写回超级块
    disk->write(root_block, inode_block.Data);  // 写回根目录inode
    
    printf("目录结构初始化成功\n");
    return true;
}

void FileSystem::pwd() {
    // 打印当前目录的绝对路径
    printf("当前目录: %s\n", current_dir.c_str());
    
    // 打印当前目录的inode号
    printf("当前目录inode号: %u\n", current_dir_ino);
    
    // 计算并打印当前目录的物理地址信息
    uint32_t current_block = INODE_START_ADDR + (current_dir_ino / INODES_PER_BLOCK);
    uint32_t current_offset = current_dir_ino % INODES_PER_BLOCK;
    uint32_t current_phys_addr = (current_block << 16) | current_offset;
    
    printf("物理地址: 0x%08X (块号: %u, 块内偏移: %u)\n", 
           current_phys_addr, current_block, current_offset);
}

bool FileSystem::cd(Disk *disk, string dir_name) {
    Block block;
    
    // 1. 读取当前目录的inode
    uint32_t current_block = INODE_START_ADDR + (current_dir_ino / INODES_PER_BLOCK);
    uint32_t current_offset = current_dir_ino % INODES_PER_BLOCK;
    
    disk->read(current_block, block.Data);
    Inode &current_inode = block.Inodes[current_offset];
    
    // 2. 处理特殊情况
    if (dir_name == ".") {
        // 保持在当前目录
        return true;
    }
    
    // 3. 在当前目录的children中查找目标目录
    auto it = current_inode.dentry.children.find(dir_name);
    if (it == current_inode.dentry.children.end()) {
        printf("目录不存在\n");
        return false;
    }
    
    // 4. 获取目标目录的物理地址
    uint32_t target_phys_addr = it->second;
    uint32_t target_block = target_phys_addr >> 16;  // 获取块地址
    uint32_t target_offset = target_phys_addr & 0xFFFF;  // 获取块内偏移，用0xffff取低16位
    
    // 5. 读取目标目录的inode
    disk->read(target_block, block.Data);
    Inode &target_inode = block.Inodes[target_offset];
    
    // 6. 验证目标是否为目录
    if (target_inode.type != 1) {
        printf("目标不是目录\n");
        return false;
    }
    
    // 7. 更新当前目录信息
    uint32_t target_ino = ((target_block - INODE_START_ADDR) * INODES_PER_BLOCK) + target_offset;
    current_dir_ino = target_ino;
    
    // 8. 更新当前路径
    if (dir_name == "..") {
        // 处理返回上级目录的情况
        if (current_dir == "/") {
            // 已经在根目录，保持不变
            printf("已经在根目录\n");
            return true;
        }
        size_t last_slash = current_dir.find_last_of('/'); //如果 current_dir 是 "/home/user"，last_slash 将是 5 
        if (last_slash == 0) { //如果 current_dir 是 "/home"，last_slash 将是 0
            current_dir = "/";  // 返回根目录
        } else {
            current_dir = current_dir.substr(0, last_slash);
        }
    } else {
        // 处理进入子目录的情况
        if (current_dir == "/") {
            current_dir += dir_name;
        } else {
            current_dir += "/" + dir_name;
        }
    }
    
    return true;
}

void FileSystem::ls(Disk *disk) {
    Block block;
    
    // 1. 读取当前目录的inode
    uint32_t current_block = INODE_START_ADDR + (current_dir_ino / INODES_PER_BLOCK);
    uint32_t current_offset = current_dir_ino % INODES_PER_BLOCK;
    
    disk->read(current_block, block.Data);
    Inode &current_inode = block.Inodes[current_offset];
    // 打印表头
    printf("%-9s %-15s %8s %s\n", "权限", "所有者", "大小", "名称");
    printf("-----------------------------------------\n");
    // 2. 遍历当前目录的所有子项
    printf("当前目录的子项数: %u, 目录inode号为%u\n", current_inode.dentry.children.size(), current_dir_ino);
    
    map<string,uint32_t>::iterator it = current_inode.dentry.children.begin();
    size_t count = current_inode.dentry.children.size();
    for (size_t i = 0; i < count; i++, ++it) {
        // 跳过空键
        if (it->first.empty()) {
            continue;
        }
        
        // 获取子项的物理地址
        uint32_t child_phys_addr = it->second;
        uint32_t child_block = child_phys_addr >> 16;
        uint32_t child_offset = child_phys_addr & 0xFFFF;
        
        // 读取子项的inode
        Block child_block_data;
        disk->read(child_block, child_block_data.Data);
        Inode &child_inode = child_block_data.Inodes[child_offset];
        
        // 3. 构建权限字符串
        string perm;
        if (child_inode.type == 1) {
            perm = "d";  // 目录
        } else {
            perm = "-";  // 文件
        }
        
        // 解析mode（0x77 = rwxrwx）
        uint8_t mode = child_inode.mode;
        // 所有者权限
        perm += ((mode & 0x40) ? "r" : "-");  // 读权限 (0x40 = 0100 0000)
        perm += ((mode & 0x20) ? "w" : "-");  // 写权限 (0x20 = 0010 0000)
        perm += ((mode & 0x10) ? "x" : "-");  // 执行权限 (0x10 = 0001 0000)
        // others权限
        perm += ((mode & 0x04) ? "r" : "-");  // 读权限 (0x04 = 0000 0100)
        perm += ((mode & 0x02) ? "w" : "-");  // 写权限 (0x02 = 0000 0010)
        perm += ((mode & 0x01) ? "x" : "-");  // 执行权限 (0x01 = 0000 0001)
        
        // 4. 格式化输出
        printf("%-9s %-15s %8u %s\n",
               perm.c_str(),              // 权限
               child_inode.uname.c_str(), // 所有者
               child_inode.Size,          // 大小
               it->first.c_str());        // 名称
    }
}

bool FileSystem::create(Disk *disk, string file_path) {
    Block block;
    
    // 1. 检查路径名是否合法
    if (file_path.empty() || file_path.length() > 255) {
        printf("路径名不合法\n");
        return false;
    }

    // 2. 解析路径
    string parent_path = "/";  // 父目录的路径
    string file_name;          // 要创建的文件名
    uint32_t parent_ino;      // 父目录的inode号

    // 处理不同的路径格式
    if (file_path[0] == '/') {
        // 绝对路径，从根目录开始
        parent_ino = 0;  // 根目录的inode号
        if (file_path == "/") {
            printf("无法创建根目录\n");
            return false;
        }
        // 移除开头的'/'
        file_path = file_path.substr(1);
        parent_path = "/";
    } else if (file_path.substr(0, 2) == "./") {
        // 当前目录路径
        parent_ino = current_dir_ino;
        parent_path = current_dir;
        // 移除"./"
        file_path = file_path.substr(2);
    } else {
        // 相对路径，从当前目录开始
        parent_ino = current_dir_ino;
        parent_path = current_dir;
    }

    // 3. 如果路径中包含多级目录，需要逐级查找
    size_t pos = file_path.find('/');
    while (pos != string::npos) {
        string segment = file_path.substr(0, pos);
        file_path = file_path.substr(pos + 1);

        // 处理 ".." 目录
        if (segment == "..") {
            // 获取当前目录的inode
            uint32_t current_block = INODE_START_ADDR + (parent_ino / INODES_PER_BLOCK);
            uint32_t current_offset = parent_ino % INODES_PER_BLOCK;
            disk->read(current_block, block.Data);
            Inode &current_inode = block.Inodes[current_offset];
            
            // 获取父目录的物理地址
            auto it = current_inode.dentry.children.find("..");
            if (it == current_inode.dentry.children.end()) {
                printf("无法访问父目录\n");
                return false;
            }
            
            uint32_t parent_phys_addr = it->second;
            parent_ino = ((parent_phys_addr >> 16) - INODE_START_ADDR) * INODES_PER_BLOCK + (parent_phys_addr & 0xFFFF);
            
            // 更新父目录路径
            size_t last_slash = parent_path.find_last_of('/');
            if (last_slash == 0) {
                parent_path = "/";
            } else {
                parent_path = parent_path.substr(0, last_slash);
            }
        } else {
            // 读取当前目录的inode
            uint32_t current_block = INODE_START_ADDR + (parent_ino / INODES_PER_BLOCK);
            uint32_t current_offset = parent_ino % INODES_PER_BLOCK;
            disk->read(current_block, block.Data);
            Inode &current_inode = block.Inodes[current_offset];

            // 查找子目录
            auto it = current_inode.dentry.children.find(segment);
            if (it == current_inode.dentry.children.end()) {
                printf("路径不存在: %s\n", segment.c_str());
                return false;
            }

            // 更新父目录信息
            uint32_t child_phys_addr = it->second;
            parent_ino = ((child_phys_addr >> 16) - INODE_START_ADDR) * INODES_PER_BLOCK + (child_phys_addr & 0xFFFF);
            parent_path = parent_path == "/" ? "/" + segment : parent_path + "/" + segment;
        }
        
        pos = file_path.find('/');
    }

    // 4. 最后一段是要创建的文件名
    file_name = file_path;
    if (file_name == "." || file_name == "..") {
        printf("无法创建名为 . 或 .. 的文件\n");
        return false;
    }

    // 5. 读取父目录的inode
    uint32_t parent_block = INODE_START_ADDR + (parent_ino / INODES_PER_BLOCK);
    uint32_t parent_offset = parent_ino % INODES_PER_BLOCK;
    uint32_t parent_phys_addr = (parent_block << 16) | parent_offset;
    
    disk->read(parent_block, block.Data);
    Inode &parent_inode = block.Inodes[parent_offset]; // 获取当前目录的inode

    // 6. 检查文件是否已存在
    if (parent_inode.dentry.children.find(file_name) != parent_inode.dentry.children.end()) {
        printf("文件已存在: %s\n", file_name.c_str());
        return false;
    }

    // 7. 分配新的inode
    int new_ino = allocate_inode(disk);
    if (new_ino == -1) {
        printf("没有空闲inode\n");
        return false;
    }

    // 8. 初始化新文件的inode
    uint32_t new_inode_block = INODE_START_ADDR + (new_ino / INODES_PER_BLOCK);
    uint32_t new_inode_offset = new_ino % INODES_PER_BLOCK;
    uint32_t new_phys_addr = (new_inode_block << 16) | new_inode_offset;
    
    disk->read(new_inode_block, block.Data);
    Inode &new_inode = block.Inodes[new_inode_offset]; // 获取新文件的inode
    
    new_inode.Valid = 1;  // 设置新文件的inode已使用
    new_inode.Size = 0;  // 新文件初始大小为0
    new_inode.type = 0;  // 0表示文件
    new_inode.mode = DEFAULT_MODE;  // 默认权限
    new_inode.uname = current_user;  // 设置文件所有者
    new_inode.dentry.name = file_name;  // 设置文件名
    memset(new_inode.Direct, 0, sizeof(new_inode.Direct));
    new_inode.Indirect = 0;

    // 6. 更新父目录
    parent_inode.dentry.children[file_name] = new_phys_addr;
    //parent_inode.Size += 32;  // 文件不需要初始化大小
    
    // 7. 写回磁盘
    disk->write(parent_block, block.Data);  // 写回父目录inode
    disk->write(new_inode_block, block.Data);  // 写回新文件inode
    
    printf("文件创建成功: %s%s%s\n", 
           parent_path.c_str(),
           (parent_path == "/" ? "" : "/"),
           file_name.c_str());
    return true;
}

bool FileSystem::vi(Disk *disk, string file_path) {
    Block block;
    
    // 1. 解析路径，找到文件的inode
    string parent_path = "/";  // 父目录的路径
    string file_name;          // 文件名
    uint32_t parent_ino;      // 父目录的inode号

    // 处理不同的路径格式
    if (file_path[0] == '/') {
        // 绝对路径，从根目录开始
        parent_ino = 0;
        if (file_path == "/") {
            printf("无法编辑根目录\n");
            return false;
        }
        file_path = file_path.substr(1);
        parent_path = "/";
    } else if (file_path.substr(0, 2) == "./") {
        // 当前目录路径
        parent_ino = current_dir_ino;
        parent_path = current_dir;
        file_path = file_path.substr(2);
    } else {
        // 相对路径，从当前目录开始
        parent_ino = current_dir_ino;
        parent_path = current_dir;
    }

    // 2. 如果路径中包含多级目录，需要逐级查找
    size_t pos = file_path.find('/');
    while (pos != string::npos) {
        string segment = file_path.substr(0, pos);
        file_path = file_path.substr(pos + 1);

        // 处理 ".." 目录
        if (segment == "..") {
            // 获取当前目录的inode
            uint32_t current_block = INODE_START_ADDR + (parent_ino / INODES_PER_BLOCK);
            uint32_t current_offset = parent_ino % INODES_PER_BLOCK;
            disk->read(current_block, block.Data);
            Inode &current_inode = block.Inodes[current_offset];
            
            // 获取父目录的物理地址
            auto it = current_inode.dentry.children.find("..");
            if (it == current_inode.dentry.children.end()) {
                printf("无法访问父目录\n");
                return false;
            }
            
            uint32_t parent_phys_addr = it->second;
            parent_ino = ((parent_phys_addr >> 16) - INODE_START_ADDR) * INODES_PER_BLOCK + (parent_phys_addr & 0xFFFF);
            
            // 更新父目录路径
            size_t last_slash = parent_path.find_last_of('/');
            if (last_slash == 0) {
                parent_path = "/";
            } else {
                parent_path = parent_path.substr(0, last_slash);
            }
        } else {
            // 读取当前目录的inode
            uint32_t current_block = INODE_START_ADDR + (parent_ino / INODES_PER_BLOCK);
            uint32_t current_offset = parent_ino % INODES_PER_BLOCK;
            disk->read(current_block, block.Data);
            Inode &current_inode = block.Inodes[current_offset];

            // 查找子目录
            auto it = current_inode.dentry.children.find(segment);
            if (it == current_inode.dentry.children.end()) {
                printf("路径不存在: %s\n", segment.c_str());
                return false;
            }

            // 更新父目录信息
            uint32_t child_phys_addr = it->second;
            parent_ino = ((child_phys_addr >> 16) - INODE_START_ADDR) * INODES_PER_BLOCK + (child_phys_addr & 0xFFFF);
            parent_path = parent_path == "/" ? "/" + segment : parent_path + "/" + segment;
        }
        
        pos = file_path.find('/');
    }

    // 3. 最后一段是文件名
    file_name = file_path;
    if (file_name == "." || file_name == "..") {
        printf("无法编辑 . 或 .. 目录\n");
        return false;
    }

    // 4. 读取父目录的inode
    uint32_t parent_block = INODE_START_ADDR + (parent_ino / INODES_PER_BLOCK);
    uint32_t parent_offset = parent_ino % INODES_PER_BLOCK;
    disk->read(parent_block, block.Data);
    Inode &parent_inode = block.Inodes[parent_offset];

    // 5. 查找文件
    auto it = parent_inode.dentry.children.find(file_name);
    if (it == parent_inode.dentry.children.end()) {
        // 如果文件不存在，创建新文件
        if (!create(disk, file_path)) {
            printf("创建文件失败\n");
            return false;
        }
        // 重新读取父目录的inode，因为create函数修改了children属性
        disk->read(parent_block, block.Data);
        parent_inode = block.Inodes[parent_offset];
        // 重新查找文件
        it = parent_inode.dentry.children.find(file_name);
    }

    // 6. 获取文件的inode
    uint32_t file_phys_addr = it->second;  
    uint32_t file_block = file_phys_addr >> 16;  // 获取文件inode块地址
    uint32_t file_offset = file_phys_addr & 0xFFFF;  // 获取文件inode块内偏移
    disk->read(file_block, block.Data);  // 读取inode所在块
    Inode &file_inode = block.Inodes[file_offset];  // 获取文件的inode

    // 7. 检查是否为文件
    if (file_inode.type != 0) {
        printf("不能编辑目录\n");
        return false;
    }

    // 8. 读取文件内容
    char buffer[Disk::BLOCK_SIZE] = {0};
    if (file_inode.Size > 0) {
        // 如果文件不为空，读取内容。(file_block(文件inode块地址) - INODE_START_ADDR) * INODES_PER_BLOCK + file_offset(文件inode块内偏移)计算文件的inode号  
        read(disk, ((file_block - INODE_START_ADDR) * INODES_PER_BLOCK + file_offset), buffer, file_inode.Size);
        printf("当前文件内容:\n%s\n", buffer);
    }

    // 9. 进入编辑模式
    printf("进入编辑模式 (输入:wq保存并退出, 输入:q!不保存退出):\n");
    string content;
    string line;
    while (getline(cin, line)) { // 从标准输入流中读取一行，注意文件内容是按行存储的，每行以\n结尾
        if (line == ":wq") {
            // 保存并退出
            write(disk, ((file_block - INODE_START_ADDR) * INODES_PER_BLOCK + file_offset), 
                  (char*)content.c_str(), content.length());
            printf("文件已保存\n");
            break;
        } else if (line == ":q!") {
            // 不保存退出
            printf("退出编辑器，文件未保存\n");
            break;
        } else {
            // 添加内容
            content += line + "\n";
        }
    }

    return true;
}

// 释放数据块
void FileSystem::free_blocks(Disk *disk, uint32_t *blocks, size_t count) {
    Block super_block;
    disk->read(0, super_block.Data);
    SuperBlock &sb = super_block.Super;

    for (size_t i = 0; i < count; i++) {
        if (blocks[i] != 0) {
            b_map[blocks[i]] = false;  // 标记为未使用
            sb.s_free_block_count++;
            if (blocks[i] < sb.next_available_blk) {
                sb.next_available_blk = blocks[i];
            }
        }
    }
    disk->write(0, super_block.Data);
}

// 释放inode
void FileSystem::free_inode(Disk *disk, uint32_t ino) {
    Block super_block;
    disk->read(0, super_block.Data);
    SuperBlock &sb = super_block.Super;

    // 读取inode所在的块
    uint32_t inode_block = INODE_START_ADDR + (ino / INODES_PER_BLOCK);
    uint32_t inode_offset = ino % INODES_PER_BLOCK;
    Block block;
    disk->read(inode_block, block.Data);
    
    // 将inode的Valid字段设置为0
    block.Inodes[inode_offset].Valid = 0;
    disk->write(inode_block, block.Data);

    // 更新位图和超级块
    i_map[ino] = false;  // 标记为未使用
    sb.free_inode_count++;
    if (ino < sb.next_available_ino) {
        sb.next_available_ino = ino;
    }
    disk->write(0, super_block.Data);
}

// 递归删除目录
bool FileSystem::remove_directory(Disk *disk, uint32_t dir_ino) {
    Block block;
    uint32_t dir_block = INODE_START_ADDR + (dir_ino / INODES_PER_BLOCK);
    uint32_t dir_offset = dir_ino % INODES_PER_BLOCK;
    
    disk->read(dir_block, block.Data);
    Inode &dir_inode = block.Inodes[dir_offset];
    
    // 遍历目录中的所有项
    map<string,uint32_t>::iterator it = dir_inode.dentry.children.begin();
    size_t count = dir_inode.dentry.children.size();
    for (size_t i = 0; i < count; i++, ++it) {
        // 跳过 "." 和 ".." 目录
        if (it->first == "." || it->first == "..") {
            continue;
        }
        
        // 获取子项的inode
        uint32_t child_phys_addr = it->second;
        uint32_t child_block = child_phys_addr >> 16;
        uint32_t child_offset = child_phys_addr & 0xFFFF;
        uint32_t child_ino = ((child_block - INODE_START_ADDR) * INODES_PER_BLOCK) + child_offset;
        
        Block child_block_data;
        disk->read(child_block, child_block_data.Data);
        Inode &child_inode = child_block_data.Inodes[child_offset];
        
        // 如果是目录，递归删除
        if (child_inode.type == 1) {
            if (!remove_directory(disk, child_ino)) {
                printf("递归删除目录失败\n");
                return false;
            }
        } else {
            // 如果是文件，释放数据块
            free_blocks(disk, child_inode.Direct, POINTERS_PER_INODE);
            if (child_inode.Indirect != 0) {
                // 读取间接块
                Block indirect_block;
                disk->read(child_inode.Indirect, indirect_block.Data);
                // 释放间接块指向的数据块
                free_blocks(disk, indirect_block.Pointers, POINTERS_PER_BLOCK);
                // 释放间接块本身
                b_map[child_inode.Indirect] = false;
            }
            // 释放文件的inode
            free_inode(disk, child_ino);
        }
    }
    
    // 释放目录的数据块
    free_blocks(disk, dir_inode.Direct, POINTERS_PER_INODE);
    if (dir_inode.Indirect != 0) {
        Block indirect_block;
        disk->read(dir_inode.Indirect, indirect_block.Data);
        free_blocks(disk, indirect_block.Pointers, POINTERS_PER_BLOCK);
        b_map[dir_inode.Indirect] = false;
    }
    
    // 释放目录的inode
    free_inode(disk, dir_ino);
    
    return true;
}

// 删除文件
bool FileSystem::remove_file(Disk *disk, uint32_t file_ino) {
    Block block;
    uint32_t file_block = INODE_START_ADDR + (file_ino / INODES_PER_BLOCK);
    uint32_t file_offset = file_ino % INODES_PER_BLOCK;  // 获取文件的inode块地址和inode块内偏移
    
    disk->read(file_block, block.Data);
    Inode &file_inode = block.Inodes[file_offset];  // 获取文件的inode
    
    // 释放文件的数据块
    free_blocks(disk, file_inode.Direct, POINTERS_PER_INODE);  // 释放文件的直接块
    if (file_inode.Indirect != 0) {
        // 读取间接块
        Block indirect_block;
        disk->read(file_inode.Indirect, indirect_block.Data);
        // 释放间接块指向的数据块
        free_blocks(disk, indirect_block.Pointers, POINTERS_PER_BLOCK);
        // 释放间接块本身
        b_map[file_inode.Indirect] = false;
    }
    
    // 释放文件的inode
    free_inode(disk, file_ino);
    
    return true;
}

bool FileSystem::remove(Disk *disk, string path) {
    Block block;
    
    // 1. 解析路径
    string parent_path = "/";
    string target_name;
    uint32_t parent_ino;

    // 处理不同的路径格式
    if (path[0] == '/') {
        parent_ino = 0;
        if (path == "/") {
            printf("无法删除根目录\n");
            return false;
        }
        path = path.substr(1);
        parent_path = "/";
    } else if (path.substr(0, 2) == "./") {
        parent_ino = current_dir_ino;
        parent_path = current_dir;
        path = path.substr(2);
    } else {
        parent_ino = current_dir_ino;
        parent_path = current_dir;
    }

    // 2. 处理路径中的目录
    size_t pos = path.find('/');
    while (pos != string::npos) {
        string segment = path.substr(0, pos);
        path = path.substr(pos + 1);

        if (segment == "..") {
            uint32_t current_block = INODE_START_ADDR + (parent_ino / INODES_PER_BLOCK);
            uint32_t current_offset = parent_ino % INODES_PER_BLOCK;
            disk->read(current_block, block.Data);
            Inode &current_inode = block.Inodes[current_offset];
            
            auto it = current_inode.dentry.children.find("..");
            if (it == current_inode.dentry.children.end()) {
                printf("无法访问父目录\n");
                return false;
            }
            
            uint32_t parent_phys_addr = it->second;
            parent_ino = ((parent_phys_addr >> 16) - INODE_START_ADDR) * INODES_PER_BLOCK + (parent_phys_addr & 0xFFFF);
            
            size_t last_slash = parent_path.find_last_of('/');
            if (last_slash == 0) {
                parent_path = "/";
            } else {
                parent_path = parent_path.substr(0, last_slash);
            }
        } else {
            uint32_t current_block = INODE_START_ADDR + (parent_ino / INODES_PER_BLOCK);
            uint32_t current_offset = parent_ino % INODES_PER_BLOCK;
            disk->read(current_block, block.Data);
            Inode &current_inode = block.Inodes[current_offset];

            auto it = current_inode.dentry.children.find(segment);
            if (it == current_inode.dentry.children.end()) {
                printf("路径不存在: %s\n", segment.c_str());
                return false;
            }

            uint32_t child_phys_addr = it->second;
            parent_ino = ((child_phys_addr >> 16) - INODE_START_ADDR) * INODES_PER_BLOCK + (child_phys_addr & 0xFFFF);
            parent_path = parent_path == "/" ? "/" + segment : parent_path + "/" + segment;
        }
        
        pos = path.find('/');
    }

    // 3. 最后一段是要删除的文件/目录名
    target_name = path;
    if (target_name == "." || target_name == "..") {
        printf("无法删除 . 或 .. 目录\n");
        return false;
    }

    // 4. 读取父目录的inode
    uint32_t parent_block = INODE_START_ADDR + (parent_ino / INODES_PER_BLOCK);
    uint32_t parent_offset = parent_ino % INODES_PER_BLOCK;
    disk->read(parent_block, block.Data);
    Inode &parent_inode = block.Inodes[parent_offset];

    // 5. 查找目标文件/目录
    auto it = parent_inode.dentry.children.find(target_name);
    if (it == parent_inode.dentry.children.end()) {
        printf("文件或目录不存在: %s\n", target_name.c_str());
        return false;
    }

    // 6. 获取目标的inode
    uint32_t target_phys_addr = it->second;
    uint32_t target_block = target_phys_addr >> 16;
    uint32_t target_offset = target_phys_addr & 0xFFFF;
    uint32_t target_ino = ((target_block - INODE_START_ADDR) * INODES_PER_BLOCK) + target_offset;

    Block target_block_data;
    disk->read(target_block, target_block_data.Data);
    Inode &target_inode = target_block_data.Inodes[target_offset];

    // 7. 根据类型进行删除
    bool success;
    if (target_inode.type == 1) {
        // 目录：递归删除
        success = remove_directory(disk, target_ino);
        if (success) {
            printf("成功删除目录: %s\n", target_name.c_str());
        }
    } else {
        // 文件：删除文件
        success = remove_file(disk, target_ino);
        if (success) {
            printf("成功删除文件: %s\n", target_name.c_str());
        }
    }

    if (!success) {
        return false;
    }

    // 8. 从父目录中移除
    parent_block = INODE_START_ADDR + (parent_ino / INODES_PER_BLOCK);
    parent_offset = parent_ino % INODES_PER_BLOCK;
    disk->read(parent_block, block.Data);
    parent_inode = block.Inodes[parent_offset];
    it = parent_inode.dentry.children.find(target_name);

    parent_inode.dentry.children.erase(it);
    parent_inode.Size -= 32;  // 减少目录项大小
    disk->write(parent_block, block.Data);

    return true;
}

bool FileSystem::cat(Disk *disk, string file_path) {
    Block block;
    
    // 1. 解析路径
    string parent_path = "/";
    string file_name;
    uint32_t parent_ino;

    // 处理不同的路径格式
    if (file_path[0] == '/') {
        parent_ino = 0;
        if (file_path == "/") {
            printf("无法读取根目录\n");
            return false;
        }
        file_path = file_path.substr(1);
        parent_path = "/";
    } else if (file_path.substr(0, 2) == "./") {
        parent_ino = current_dir_ino;
        parent_path = current_dir;
        file_path = file_path.substr(2);
    } else {
        parent_ino = current_dir_ino;
        parent_path = current_dir;
    }

    // 2. 处理路径中的目录
    size_t pos = file_path.find('/');
    while (pos != string::npos) {
        string segment = file_path.substr(0, pos);
        file_path = file_path.substr(pos + 1);

        if (segment == "..") {
            uint32_t current_block = INODE_START_ADDR + (parent_ino / INODES_PER_BLOCK);
            uint32_t current_offset = parent_ino % INODES_PER_BLOCK;
            disk->read(current_block, block.Data);
            Inode &current_inode = block.Inodes[current_offset];
            
            auto it = current_inode.dentry.children.find("..");
            if (it == current_inode.dentry.children.end()) {
                printf("无法访问父目录\n");
                return false;
            }
            
            uint32_t parent_phys_addr = it->second;
            parent_ino = ((parent_phys_addr >> 16) - INODE_START_ADDR) * INODES_PER_BLOCK + (parent_phys_addr & 0xFFFF);
            
            size_t last_slash = parent_path.find_last_of('/');
            if (last_slash == 0) {
                parent_path = "/";
            } else {
                parent_path = parent_path.substr(0, last_slash);
            }
        } else {
            uint32_t current_block = INODE_START_ADDR + (parent_ino / INODES_PER_BLOCK);
            uint32_t current_offset = parent_ino % INODES_PER_BLOCK;
            disk->read(current_block, block.Data);
            Inode &current_inode = block.Inodes[current_offset];

            auto it = current_inode.dentry.children.find(segment);
            if (it == current_inode.dentry.children.end()) {
                printf("路径不存在: %s\n", segment.c_str());
                return false;
            }

            uint32_t child_phys_addr = it->second;
            parent_ino = ((child_phys_addr >> 16) - INODE_START_ADDR) * INODES_PER_BLOCK + (child_phys_addr & 0xFFFF);
            parent_path = parent_path == "/" ? "/" + segment : parent_path + "/" + segment;
        }
        
        pos = file_path.find('/');
    }

    // 3. 最后一段是文件名
    file_name = file_path;
    if (file_name == "." || file_name == "..") {
        printf("无法读取 . 或 .. 目录\n");
        return false;
    }

    // 4. 读取父目录的inode
    uint32_t parent_block = INODE_START_ADDR + (parent_ino / INODES_PER_BLOCK);
    uint32_t parent_offset = parent_ino % INODES_PER_BLOCK;
    disk->read(parent_block, block.Data);
    Inode &parent_inode = block.Inodes[parent_offset];

    // 5. 查找文件
    auto it = parent_inode.dentry.children.find(file_name);
    if (it == parent_inode.dentry.children.end()) {
        printf("文件不存在: %s\n", file_name.c_str());
        return false;
    }

    // 6. 获取文件的inode
    uint32_t file_phys_addr = it->second;
    uint32_t file_block = file_phys_addr >> 16;
    uint32_t file_offset = file_phys_addr & 0xFFFF;
    uint32_t file_ino = ((file_block - INODE_START_ADDR) * INODES_PER_BLOCK) + file_offset;

    disk->read(file_block, block.Data);
    Inode &file_inode = block.Inodes[file_offset];

    // 7. 检查是否为文件
    if (file_inode.type != 0) {
        printf("不能读取目录内容\n");
        return false;
    }

    // 8. 读取并打印文件内容
    if (file_inode.Size > 0) {
        char *buffer = new char[file_inode.Size + 1];  // +1 for null terminator
        memset(buffer, 0, file_inode.Size + 1);
        
        // 读取文件内容
        ssize_t bytes_read = read(disk, file_ino, buffer, file_inode.Size);
        if (bytes_read < 0) {
            printf("读取文件失败\n");
            delete[] buffer;
            return false;
        }
        
        // 打印文件内容
        printf("%s", buffer);
        
        delete[] buffer;
    }

    return true;
}

void FileSystem::clear() {
    // 使用ANSI转义序列清空屏幕并将光标移动到开头
    system("clear");
}
